<template>
  <div
    @mouseenter="changeMoveHandle(true)"
    @mouseleave="changeMoveHandle(false)"
    @click="$event.stopPropagation()"
    @mousewheel="$event.stopPropagation()"
  >
    <BaseControlTemplate
      class="table"
      :class="{'hide-after': pageViewMode === 'design' || pageViewMode === 'runtime',}"
      :new-params="newParams"
      :page-view-mode="pageViewMode"
      :readonly="readonly"
      :model-value="modelValue"
      :validate-error="validateError"
      :save-dialog-config="saveDialogConfig"
    >
      <template>
        <div
          v-if="loadEnd"
          class="content-table"
          :class="{ full: showFull }"
          :style="{ height: tableHeight }"
        >
          <iframe
            v-if="!iframeParams.src"
            ref="myIframe"
            width="100%"
            height="100%"
            frameborder="0"
            :src="iframeParams.url"
          >
          </iframe>
          <img v-else class="table-print_img" :src="iframeParams.src" alt="" />
        </div>
      </template>
    </BaseControlTemplate>
  </div>
</template>

<script>
import mixins from "../../mixins/vue.js";
import { deepClone } from "../../utils";
import { getTableLuckysheetUrl } from "../../api/Eln/ElnTableLuckysheet";
export default {
  name: "ControlTable",
  mixins: [mixins],
  data() {
    return {
      newParams: {},
      newParams2: {},
      loadEnd: false,
      options: {},
      tableHeight: "300px",
      showFull: false,
      // customBgcColorRgba: ['rgba(255,213,213,0.6)', "rgba(255,240,203,0.6)", "rgba(255,252,204,0.6)", "rgba(223,255,207,0.6)", "rgba(186,255,207,0.6)", "rgba(198,255,243,0.6)", "rgba(184,231,255,0.6)", "	rgba(190,207,255,0.6)", "rgba(202,190,255,0.6)", "	rgba(241,190,255,0.6)"],
      // colorIndex: 0

      // 处理从打印页面返回时，将加重颜色字体还原的配置集合(表格加载完成再去设置)
      afterLoadSetCellList: [],

      // iframe通讯参数
      iframeParams: {
        loadEnd: false,
        times: 0,
        sheetConfig: "",
        src: "",
        url: "",
      },

      tagConfigClass: "",
    };
  },
  watch: {
    pageViewMode: {
      handler(newVal, oldVal) {
        // 预览打印的情况下，设置为白色背景色
        // if (newVal === "print" || oldVal === "print") {
        //   console.log("打印设置背景为白色");
        //   const copyParams = deepClone(this.newParams);
        //   console.log(copyParams);
        //   copyParams.value.celldata.forEach((x) => {
        //     if (!x.v || !x.v.m) return;
        //     const v = this.newParams2.value.data.find((y, i) => i === x.r)[x.c];
        //     if (Object.prototype.hasOwnProperty.call(x.v, "bg")) {
        //       if (newVal === "print") {
        //         x.v.bg = "#fff";
        //         x.v.bl = 1;
        //         x.v.v = x.v.m = v.v;
        //         luckysheetInstance.setCellValue(x.r, x.c, x.v, {}, true);
        //       } else {
        //         x.v.bl = v.bl;
        //         x.v.v = x.v.m = v.v;
        //         this.afterLoadSetCellList.push(x);
        //       }
        //     } else {
        //       if (newVal === "print") {
        //         x.v.bl = 1;
        //         luckysheetInstance.setCellValue(x.r, x.c, x.v, {}, true);
        //       } else {
        //         x.v.bl = v.bl;
        //         this.afterLoadSetCellList.push(x);
        //       }
        //     }
        //   });
        //   console.log("循环完成");
        // }
      },
    },
  },
  mounted() {
    this.newParams = deepClone(this.params);
    this.newParams2 = deepClone(this.params);
    this.loadEnd = true;
    getTableLuckysheetUrl().then((res) => {
      const { data } = res;
      if (!data || data.length === 0) {
        return this.$message.error("加载表格需先在数据字典配置LuckySheet地址!");
      }
      this.iframeParams.url = data[0].value;
      this.init(0);
    });
    window.addEventListener("click", this.cancelCellSelect);
  },
  beforeDestroy() {
    this.sendMessageToIframe({ code: "destroy" });
    window.removeEventListener("click", this.cancelCellSelect);
    window.removeEventListener("message", this.listenMessageFromIframe);
    this.$refs.myIframe?.remove();
  },
  methods: {
    // 点击外部，取消单元格的选中效果
    cancelCellSelect(e) {
      // 防止点击增加行列出现问题 || 点击回退或者删除按键触发此事件
      if (
        event.target.className === "luckysheet-mousedown-cancel" ||
        event.target.id === "luckysheet-delete-text" ||
        event.target.className.includes(this.tagConfigClass)
      ) {
        return;
      }
      this.sendMessageToIframe({ code: "cancelCellSelect" });
    },
    // type: 0: 页面初始化 1: 设置全屏与非全屏  2: 打印之后返回重新加载iframe
    init(type) {
      if (type === 0) {
        // 设计时
        if (this.pageViewMode === "design") {
          this.options = !this.newParams.defaultValue
            ? this.createDefaultOptions()
            : this.newParams.defaultValue.body
              ? this.convertDataStruct()
              : this.createDefaultOptions(this.newParams.defaultValue);
        } else {
          this.options = this.convertDataStruct();
        }
      }
      this.options.defaultFontSize=12
      this.tableHeight = this.showFull
        ? document.body.offsetHeight + "px"
        : "300px";

      // 向iframe页面发送加载事件
      const iframeInitFn = () => {
        const message = {
          code: "init",
          data: {
            config: this.options,
          },
        };
        this.sendMessageToIframe(message);
      };

      if (type === 1) {
        this.options.showtoolbarConfig.full = !this.showFull;
        this.options.showtoolbarConfig.unfull = this.showFull;
        this.options.data = [this.iframeParams.sheetConfig];
        iframeInitFn();
      }
      this.$nextTick(() => {
        const myIframe = this.$refs.myIframe;
        myIframe.addEventListener("load", () => {
          this.iframeParams.loadEnd = true;
          iframeInitFn();
          window.removeEventListener("message", this.listenMessageFromIframe);
          // 接收iframe页面发送来的事件
          window.addEventListener("message", this.listenMessageFromIframe);
        });
      });
    },
    // 监听iframe页面回馈的事件
    listenMessageFromIframe(event) {
      if (this.iframeParams.url.indexOf(event.origin) === -1) return;
      const param = JSON.parse(event.data);
      const { code, data, id } = param;
      if (id !== this.newParams.id) return;
      switch (code) {
        // 设置全屏与非全屏
        case "setFull":
          this.showFull = data;
          this.init(1);
          break;
        // 获取配置信息
        case "getConfig":
          this.iframeParams.sheetConfig = data;
          break;
        // 将表格转换为图片
        case "getRangeSrc":
          this.iframeParams.src = data;
          this.iframeParams.loadEnd = false;
          break;
        // 表格加载完的回调
        case "workbookCreateAfter":
          this.$emit("tableLoadHandle");
          break;
        // 选中最终值得回调
        case "setTagConfig":
          param["title"] = this.newParams.label;
          console.log(this.newParams);
          this.$emit("tagValue2Select", param);
          break;
        default:
          break;
      }
      this.iframeParams.times > 0 && this.iframeParams.times--;
    },
    // 向iframe页面发送事件
    sendMessageToIframe(message, origin = this.iframeParams.url) {
      if (!this.iframeParams.loadEnd) return;
      const myIframe = this.$refs.myIframe;
      const iframeWindow = myIframe?.contentWindow;
      if (!iframeWindow) return;
      // 加上唯一标识
      message.id = this.newParams.id;
      iframeWindow.postMessage(JSON.stringify(message), origin);
    },
    printExcel() {
      return new Promise((resolve, reject) => {
        this.iframeParams.times++;
        this.sendMessageToIframe({
          code: "getRangeSrc",
        });
        const timer = setInterval(() => {
          if (this.iframeParams.times === 0) {
            clearInterval(timer);
            this.tableHeight = "auto";
            resolve();
          }
        });
      });
    },

    // 创建默认配置
    createDefaultOptions(data) {
      const _this = this;
      if (data) {
        delete data.defaultRowHeight;
        delete data.defaultColWidth;
        // 兼容: 补全数据
        Array.isArray(data.data) &&
          data.data.forEach((x) => {
            if (x.length < data.column) {
              const len = data.column - x.length;
              if (len === 0) return;
              else if (len < 0) x.splice(x.length + len);
              else {
                for (let i = 0; i < len; i++) {
                  x.push(null);
                }
              }
            }
          });
      }
      const showTool =
        (this.pageViewMode === "design" || this.pageViewMode === "runtime") &&
        !this.readonly;
      const returnConfig = {
        // container: `luckysheet-${this.newParams.id}`, // luckysheet为容器id
        customAllowEdit: showTool,

        customCanvasScalc: window.devicePixelRatio === 1 ? 1 : 2,
        title: "", // 工作簿名称
        lang: "zh",
        gridKey: "1", // 唯一key
        // data: {}, // 工作表配置
        allowCopy: false, // 允许拷贝
        showtoolbar: false, // 默认工具栏都不显示
        // 自定义配置工具栏
        showtoolbarConfig: {
          undoRedo: false, // 撤销重做，注意撤消重做是两个按钮，由这一个配置决定显示还是隐藏
          paintFormat: false, // 格式刷
          currencyFormat: false, // 货币格式
          percentageFormat: false, // 百分比格式
          numberDecrease: true, // '减少小数位数'  1
          numberIncrease: true, // '增加小数位数  1
          moreFormats: false, // '更多格式'
          font: true, // '字体'
          fontSize: true, // '字号大小'
          bold: true, // '粗体 (Ctrl+B)'
          italic: false, // '斜体 (Ctrl+I)'
          strikethrough: false, // '删除线 (Alt+Shift+5)'
          underline: false, // '下划线 (Alt+Shift+6)'
          textColor: false, // '文本颜色'
          fillColor: false, // '单元格颜色'
          border: showTool, // '边框'
          mergeCell: false, // '合并单元格'
          horizontalAlignMode: true, // '水平对齐方式'  1
          verticalAlignMode: false, // '垂直对齐方式'
          textWrapMode: true, // '换行方式'  1
          textRotateMode: false, // '文本旋转方式'
          image: false, // '插入图片'
          link: false, // '插入链接'
          chart: false, // '图表'（图标隐藏，但是如果配置了chart插件，右击仍然可以新建图表）
          postil: false, // '批注'
          pivotTable: false, // '数据透视表'
          function: false, // '公式'
          frozenMode: false, // '冻结方式'
          sortAndFilter: false, // '排序和筛选'
          conditionalFormat: false, // '条件格式'
          dataVerification: false, // '数据验证'
          splitColumn: false, // '分列'
          screenshot: false, // '截图'
          findAndReplace: false, // '查找替换'
          protection: false, // '工作表保护'
          print: false, // '打印'
          tagValue: showTool, // 最终值
          full: !this.showFull,
          unfull: this.showFull,
        },
        showinfobar: false, // 标题部分信息
        showsheetbar: false, // 底部sheet页
        showsheetbarConfig: false, // 自定义底部sheet页
        showstatisticBar: false, // 底部计数栏
        // 自定义配置底部计数栏
        showstatisticBarConfig: {
          count: false, // 计数栏
          view: false, // 打印视图
          zoom: false, // 缩放
        }, // 自定义技术栏
        sheetFormulaBar: false, // 是否显示公示栏
        enableAddRow: false, // 底部添加行按钮
        accuracy: 0, // 设置精度，小数点后的位数。传参数为数字或数字字符串
        // 自定义右键单元格
        cellRightClickConfig: {
          copy: false, // 复制
          copyAs: false, // 复制为
          paste: false, // 粘贴
          insertRow: showTool, // 插入行
          insertColumn: showTool, // 插入列
          deleteRow: showTool, // 删除选中行
          deleteColumn: showTool, // 删除选中列
          deleteCell: false, // 删除单元格
          clear: false, // 清除内容
          hideRow: false, // 隐藏选中行和显示选中行
          hideColumn: false, // 隐藏选中列和显示选中列
          rowHeight: false, // 行高
          columnWidth: false, // 列宽
          matrix: false, // 矩阵操作选区
          sort: false, // 排序选区
          filter: false, // 筛选选区
          chart: false, // 图表生成
          image: false, // 插入图片
          link: false, // 插入链接
          data: false, // 数据验证
          cellFormat: false, // 设置单元格格式
        },
        rowHeaderWidth: 60,
        columnHeaderHeight: 20,
        enableAddBackTop: false,
        hook: {
          cellUpdated: (r, c, oldValue, newValue, isRefresh) => {
            if (newValue["f"]) {
              if (newValue["bg"]) return;
              newValue.bg = "rgba(255,126,0, 0.6)";
              this.sendMessageToIframe({
                code: "setCellValue",
                data: [r, c, newValue, {}, true],
              });
            } else if (oldValue && oldValue["f"] && newValue["bg"]) {
              delete newValue["bg"];
              this.sendMessageToIframe({
                code: "setCellValue",
                data: [r, c, newValue, {}, true],
              });
            }
          },
          // 表格渲染完成回调
          workbookCreateAfter() {
            // console.log("workbookCreateAfter:" + _this.pageViewMode);
            if (_this.pageViewMode === "print") {
              // const copyParams = deepClone(_this.newParams);
              // copyParams.value.celldata.forEach((x) => {
              //   if (x.v && Object.prototype.hasOwnProperty.call(x.v, "bg")) {
              //     x.v.bg = "#fff";
              //     const v = copyParams.value.data.find((y, i) => i === x.r)[x.c]
              //       ?.v;
              //     x.v.v = x.v.m = v;
              //     luckysheetInstance.setCellValue(x.r, x.c, x.v, {}, true);
              //   }
              // });
              setTimeout(() => {
                _this.$emit("tableLoadHandle");
              }, 100);
            } else {
              _this.afterLoadSetCellList.length &&
                _this.afterLoadSetCellList.forEach((x) => {
                  this.sendMessageToIframe({
                    code: "setCellValue",
                    data: [x.r, x.c, x.v, {}, true],
                  });
                });
              _this.afterLoadSetCellList.length = [];
              _this.$emit("tableLoadHandle");
            }
          },
        },
        data: [data || this.createDefaultData()],
      };
      this.pageViewMode !== "design" &&
        (returnConfig.cellRightClickConfig.customs = []);
      return returnConfig;
    },
    // 创建默认数据
    createDefaultData() {
      return {
        config: {
          merge: {},
        },
        column: 3,
        row: 3,
        luckysheet_alternateformat_save_modelCustom: [], // //自定义交替颜色
        celldata: [],
        visibledatarow: [],
        visibledatacolumn: [],
        rowsplit: [],
        ch_width: 554,
        rh_height: 300,
        defaultRowHeight: 20,
        defaultColWidth: 60,
        // "luckysheet_select_save": [],
        // "luckysheet_selection_range": [],

        tagValueList: [],
        tagCustomBorderColor: [
          "rgba(255,213,213)",
          "rgba(255,240,203)",
          "rgba(255,252,204)",
          "rgba(223,255,207)",
          "rgba(186,255,207)",
          "rgba(198,255,243)",
          "rgba(184,231,255)",
          "rgba(190,207,255)",
          "rgba(202,190,255)",
          "rgba(241,190,255)",
        ],
        tagValue2Config: [],
      };
    },
    // 转换数据结构
    convertDataStruct() {
      const convertData =
        this.pageViewMode !== "design" && this.newParams.value
          ? this.newParams.value
          : this.newParams.defaultValue;
      if (!convertData.header) {
        return this.createDefaultOptions(convertData);
      }
      // 以下为旧数据 （参照elementui的表格数据结构）
      const assembleData = [];
      const headerData = [];
      convertData.header.forEach((x) => {
        const obj =
          x.v === ""
            ? null
            : {
              v: x.v,
              m: x.v,
            };
        headerData.push(obj);
      });
      assembleData.push(headerData);

      convertData.body.forEach((data) => {
        const assemble2Data = [];
        data.forEach((x, index) => {
          if (index > convertData.header.length - 1) return;
          const obj =
            x.v === ""
              ? null
              : {
                v: x.v,
                m: x.v,
              };
          assemble2Data.push(obj);
        });
        assembleData.push(assemble2Data);
      });
      const returnData = this.createDefaultOptions();
      returnData.data[0].data = assembleData;
      return returnData;
    },
    // 重新加载组件 调整宽度
    customFn(close) {
      // flag为true代表的是关闭上级页面，下面这种情况为打印时候的全屏/非全屏展示
      if (!close && this.iframeParams.src) return;
      this.iframeParams.src = "";
      this.$nextTick(() => {
        this.init(2);
      });
    },
    // 父组件调用
    sendTagConfig(param) {
      this.tagConfigClass = param.operateClass;
      const cellData =
        param.tableId === this.newParams.id ? param.cellData : [];
      this.sendMessageToIframe({
        code: "setTagValue2Config",
        data: {
          type: param.type,
          data: cellData,
        },
      });
      console.log("table =>", cellData);
    },
    // 表格控件防止拖拽冲突，修改为仅能拖拽头部
    changeMoveHandle(flag) {
      if (this.pageViewMode !== "design") return;
      this.$emit("changeMoveHandle", flag);
    },
    // 合并去重（交集且被完全包含）
    mergeDeduplicate(config) {
      if (!config.merge || !Object.keys(config.merge).length) return;
      const checkRepeat = (v, config2) => {
        let flag = false;
        for (const k in config2) {
          const z = config2[k];
          if (
            z.c === v.c &&
            z.r === v.r &&
            z.c + z.cs === v.c + v.cs &&
            z.r + z.rs === v.r + v.rs
          ) {
            continue;
          }
          if (
            z.c <= v.c &&
            z.r <= v.r &&
            z.c + z.cs >= v.c + v.cs &&
            z.r + z.rs >= v.r + v.rs
          ) {
            flag = true;
            break;
          }
        }
        return flag;
      };
      for (const k in config.merge) {
        const v = config.merge[k];
        checkRepeat(v, config.merge) && delete config.merge[k];
      }
    },
    validate() {
      this.sendMessageToIframe({ code: "getConfig" });
      this.iframeParams.times++;
      return new Promise((resolve, reject) => {
        const tempTimer = setInterval(() => {
          if (this.iframeParams.times === 0) {
            clearInterval(tempTimer);
            const { sheetConfig } = this.iframeParams;
            sheetConfig.defaultRowHeight = 20;
            sheetConfig.defaultColWidth = 60;
            sheetConfig.column = sheetConfig.data[0]?.length || 3;
            sheetConfig.row = sheetConfig.data.length;
            this.mergeDeduplicate(sheetConfig.config);
            sheetConfig.data.forEach((xData) => {
              xData.forEach((vData) => {
                if (vData && Object.keys(vData).length) {
                  // 判断单元格是否可编辑
                  vData.read = !!(
                    !["", undefined, null].includes(vData.v) || vData.f
                  );
                  Object.prototype.hasOwnProperty.call(vData, "bg") &&
                    vData.bg &&
                    (vData.mbg = "#99FF7E00");
                }
              });
            });
            this.pageViewMode === "runtime"
              ? (this.newParams.value = sheetConfig)
              : (this.newParams.defaultValue = sheetConfig);

            resolve({
              controlValue: this.newParams,
            });
          }
        }, 100);
      });
    },
  },
};
</script>

<style lang="scss">
.content-table {
  display: flex;
  z-index: 99;
  &.full {
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
  }
  & > .table-print_img {
    max-width: 100%;
  }
}
</style>
